#include "server.h"
#include "crypto_tool.h"
#include "basic_tool.h"
#include "mpz_tool.h"
#include "config.h"
#include "memreuse.h"
#include <stdlib.h>

Server::Server()
{
  m_d = m_N = m_p = m_q = m_g = m_x = NULL;
  
}

Server::~Server()
{
  Memreuse::Delete(m_d);
  Memreuse::Delete(m_N);
  Memreuse::Delete(m_p);
  Memreuse::Delete(m_q);
  Memreuse::Delete(m_g);
  Memreuse::Delete(m_x);
}

int Server::Setup()
{
  m_d = Memreuse::New();
  m_N = Memreuse::New();
  m_p = Memreuse::New();
  m_q = Memreuse::New();
  m_g = Memreuse::New();
  m_x = Memreuse::New();
  if (Config::m_signature_protocol == "rsa")
    {
      string  strRSAPrivFile= Config::m_key_dir + "rsa.priv";
      BasicTool::Load_RSA_Priv_Key(m_d, m_N, strRSAPrivFile);
    }
  else if (Config::m_signature_protocol == "dsa")
    {
      string strDSAPubFile = Config::m_key_dir + "dsa.priv";
      BasicTool::Load_DSA_Priv_Key(m_p, m_q, m_g, m_x, strDSAPubFile);
    }
  else if (Config::m_signature_protocol == "ibe")
    {
      string strIBEServerFile = Config::m_key_dir + "ibe.server";
	  m_pairing = (pairing_t *) malloc(sizeof(pairing_t)*1);
	  m_emtR = (element_t * ) malloc(sizeof(element_t) * 1);
	  m_emtP = (element_t * ) malloc(sizeof(element_t) * 1);
	  m_emtQ = (element_t * ) malloc(sizeof(element_t) * 1);
	  m_emtz = (element_t * ) malloc(sizeof(element_t) * 1);
	  BasicTool::Load_IBE_Server_Key(m_pairing, m_emtP, m_emtQ, m_emtz, m_emtR, strIBEServerFile);
      Memreuse::InitializeElements(1000, m_pairing);
      //element_printf("%B\n", *m_emtR);
    }
  return 0;
}

int Server::PreCompute()
{
  return 0;
}


int Server::OnRequest(char * output, size_t& outLen, const size_t capacity, const char * input, const size_t inLen)
{
  mpz_t * mpzHashAtVal = Memreuse::New();
  mpz_t * mpzSig = Memreuse::New();

  MpzTool::Mpz_from_char(mpzHashAtVal, input, inLen);
  if (Config::m_signature_protocol == "rsa")
	{
	  mpz_powm(*mpzSig, *mpzHashAtVal, *m_d, *m_N);
	  MpzTool::Char_from_mpz(output, outLen, capacity, mpzSig);
	}
  else if (Config::m_signature_protocol == "dsa")
	{
	  mpz_powm(*mpzSig, *mpzHashAtVal, *m_x, *m_p);
	  MpzTool::Char_from_mpz(output, outLen, capacity, mpzSig);
	}
  else if (Config::m_signature_protocol == "ibe")
	{
	  size_t outLen = pairing_length_in_bytes_G1(*m_pairing);
	  unsigned char * data = new unsigned char [outLen];
	  element_to_bytes(data, *m_emtR);
	  memcpy(output, data, outLen);
	  assert(outLen <= capacity);
	}

  //gmp_printf("mpzhash = %Zx\n", *mpzSig);

  Memreuse::Delete(mpzHashAtVal);
  Memreuse::Delete(mpzSig);

  return 0;
}
